import os
from typing import TextIO

from bean.Constants import Constants
from bean.TableInfo import TableInfo
from builder.CommentBuilder import CommentBuilder
from utils.StringUtils import uppercase_first_char


class ServiceBuilder:

    @staticmethod
    def execute_build(table_info: TableInfo) -> None:
        if not os.path.exists(Constants.get_instance().SERVICE_PATH):
            os.makedirs(Constants.get_instance().SERVICE_PATH)

        with open(Constants.get_instance().SERVICE_PATH + f"{table_info.bean_name}Service.java", "w",
                  encoding="utf-8") as f:
            ServiceBuilder.build_class_and_imports(f, table_info)
            f.write("\n")
            ServiceBuilder.build_interfaces(f, table_info)
            f.write("\n")
            f.write("}")

    @staticmethod
    def build_class_and_imports(file_pointer: TextIO, table_info: TableInfo) -> None:
        def build_service_comment():
            if table_info.comment != "":
                CommentBuilder.build_class_comment(file_pointer, table_info.comment + " 业务接口")
            else:
                CommentBuilder.build_class_comment(file_pointer, table_info.comment)

        file_pointer.write(f"package {Constants.get_instance().PACKAGE_SERVICE};")
        file_pointer.write("\n\n")
        file_pointer.write(f"import {Constants.get_instance().PACKAGE_PO}.{table_info.bean_name};")
        file_pointer.write("\n")
        file_pointer.write(f"import {Constants.get_instance().PACKAGE_PARAM}.{table_info.bean_param_name};")
        file_pointer.write("\n")
        file_pointer.write(f"import {Constants.get_instance().PACKAGE_VO}.PaginationResultVO;")
        file_pointer.write("\n\n")
        if table_info.have_date or table_info.have_date_time:
            file_pointer.write("import java.util.Date;\n")
        if table_info.have_big_decimal:
            file_pointer.write("import java.math.BigDecimal;\n")
        file_pointer.write("import java.util.List;")

        file_pointer.write("\n")
        build_service_comment()
        file_pointer.write("\n")
        file_pointer.write(f"public interface {table_info.bean_name}Service{{")

    @staticmethod
    def build_interfaces(file_pointer: TextIO, table_info: TableInfo) -> None:
        def build_interface_helper(comment: str, content: str, retraction: str = "") -> None:
            file_pointer.write("\n")
            CommentBuilder.build_filed_comment(file_pointer, comment, retraction)
            file_pointer.write("\n")
            file_pointer.write(retraction + content)
            file_pointer.write("\n")

        build_interface_helper(
            "根据条件查询列表",
            f"List<{table_info.bean_name}> findListByParam({table_info.bean_param_name} param);",
            "\t"
        )

        build_interface_helper(
            "根据列表查询数量",
            f"Long findCountByParam({table_info.bean_param_name} param);",
            "\t"
        )

        build_interface_helper(
            "分页查询",
            f"PaginationResultVO<{table_info.bean_name}> findListByPage({table_info.bean_param_name} query);",
            "\t"
        )

        build_interface_helper(
            "新增",
            f"Integer add({table_info.bean_name} bean);",
            "\t"
        )

        build_interface_helper(
            "批量新增",
            f"Integer addBatch(List<{table_info.bean_name}> listBean);",
            "\t"
        )

        build_interface_helper(
            "批量新增/修改",
            f"Integer addOrUpdateBatch(List<{table_info.bean_name}> listBean);",
            "\t"
        )

        for i in table_info.field_map.values():
            props = uppercase_first_char(i.property_name)
            build_interface_helper(
                f"根据{i.property_name}查询",
                f"{table_info.bean_name} get{table_info.bean_name}By{props}({i.java_type} {i.property_name});",
                "\t"
            )

            build_interface_helper(
                f"根据{i.property_name}修改",
                f"Integer update{table_info.bean_name}By{props}({table_info.bean_name} bean, {i.java_type} {i.property_name});",
                "\t"
            )

            build_interface_helper(
                f"根据{i.property_name}删除",
                f"Integer delete{table_info.bean_name}By{props}({table_info.bean_name} bean, {i.java_type} {i.property_name});",
                "\t"
            )
